package com.kotlin.lib

import java.util.*
import kotlin.properties.Delegates
import kotlin.random.Random
import kotlin.reflect.KProperty

fun main() {
//    tryCatchUsage()
//    elvis()

    loop@ for (i in 1..20) {
        println("i=$i")
        for (j in 1..10) {
            if (i == 5 && j == 5) {
                break@loop
            }
            println("   j=$j")
        }
    }

    val sorted = arrayOf("hello", "world", "welcome", "hawking").filter { it.length > 5 }
        .map { it.toUpperCase(Locale.getDefault()) }.sorted()
    println(sorted)
    Example().p = "abc"

    InitOrderDemo("hello")

    println("*******************************")
    println(foo(3))

}

class Example {
    var p: String by Delegate()
}

class Delegate {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        return "$thisRef, thank you for delegating '${property.name}' to me!"
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        println("$value has been assigned to '${property.name}' in $thisRef.")
    }
}

class InitOrderDemo(name: String) {
    val firstProperty = "First property: $name".also(::println)

    init {
        println("First initializer block that prints $name")
    }

    val secondProperty = "Second property: ${name.length}".also(::println)

    init {
        println("Second initializer block that prints ${name.length}")
    }

}

fun foo(value: Int): Int {
    var result = -1
    listOf(1, 2, 3, 4).forEachIndexed { index, i ->
        if (i == value) {
            result = index
            return index
        }
        println("list of $index $i")
    }
    println("foo is done")
    return result
}

private fun elvis() {
    while (true) {
        val status = Random.nextBoolean()
        val stringVaule = if (status) "abc" else null
        println("$status string= $stringVaule")
        val result = stringVaule ?: return

        println("$result length= ${result?.length}")
        break
    }
}

/**
 * try-表达式的返回值是 try 块中的最后一个表达式或者是（所有）catch 块中的最后一个表达式。 finally 块中的内容不会影响表达式的结果。
 */
private fun tryCatchUsage() {
    val content = try {
        println("try")
        "try"
        throw Exception("hello")
    } catch (e: Exception) {
        println("exception")
        "exception"
    } finally {
        println("finally")
        "finally"

    }
    println("result is $content")
}